package org.pay.utils;



import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;


/**
 * AES CBC PKCS5 模式加密解密
 */
public class AESUtils {

    private static final String charset = "UTF-8";



    public static byte[] encrypt(byte[] data, byte[] keyBytes, byte[] ivBytes) throws Exception {
        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
        IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);

        return cipher.doFinal(data);
    }

    public static byte[] decrypt(byte[] encryptedData, byte[] keyBytes, byte[] ivBytes) throws Exception {
        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
        IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

        return cipher.doFinal(encryptedData);
    }
    /**
     * 加密
     *
     * @param content
     * @param key
     * @param iv
     * @return
     * @throws Exception
     */
    public static String encrypt(String content, String key, String iv)
            throws Exception {

        //明文
        byte[] contentBytes = content.getBytes(charset);
        //AES KEY
        byte[] keyBytes =  HexString2Bytes(key);
        //AES IV
        byte[] initParam =HexString2Bytes(iv);

        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
        //Security.addProvider(new BouncyCastleProvider());
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding","BC");


        //SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");

        IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam);

        // aes-256-cbc
       // Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivParameterSpec);
        byte[] byEnd = cipher.doFinal(contentBytes);

        //加密後的byte數組轉BASE64字符串
        String strEnd = Base64Utils.encodeStr(byEnd);
        return strEnd;
    }

    public static byte[] HexString2Bytes(String hexstr) {
        byte[] b = new byte[hexstr.length() / 2];
        int j = 0;
        for (int i = 0; i < b.length; i++) {
            char c0 = hexstr.charAt(j++);
            char c1 = hexstr.charAt(j++);
            b[i] = (byte) ((parse(c0) << 4) | parse(c1));
        }
        return b;
    }

    private static int parse(char c) {
        if (c >= 'a')
            return (c - 'a' + 10) & 0x0f;
        if (c >= 'A')
            return (c - 'A' + 10) & 0x0f;
        return (c - '0') & 0x0f;
    }


    /**
     * 解密
     *
     * @param content
     * @param key
     * @param iv
     * @return
     * @throws Exception
     */
    public static String decrypt(String content, String key, String iv)
            throws Exception {
        //反向解析BASE64字符串爲byte數組
        byte[] encryptedBytes = Base64Utils.decode(content);

        //AES KEY
       // byte[] keyBytes = key.getBytes(charset);
        //byte[] keyBytes = key.getBytes(charset);
        byte[] keyBytes =  HexString2Bytes(key);
        //AES IV
        //byte[] initParam = iv.getBytes(charset);
        byte[] initParam =HexString2Bytes(iv);

        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
        //Security.addProvider(new BouncyCastleProvider());
        //AES IV
      //  byte[] initParam = iv.getBytes(charset);


        IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam);

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding","BC");
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec);
        byte[] byEnd = cipher.doFinal(encryptedBytes);

        //加密後的byte數組直接轉字符串
        String strEnd = new String(byEnd, charset);
        return strEnd;
    }

}
